<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>WebRTC capture video and audio</title>
  <style>
    .none {
      -webkit-filter: none;
    }
    .blur {
      -webkit-filter: blur(3px);
    }
    .grayscale {
      -webkit-filter: grayscale(1);
    }
    .invert {
      -webkit-filter: invert(1);
    }
    .sepia {
      -webkit-filter: sepia(1);
    }
  </style>
</head>
<body>

<div>
  <label for="audioSource">audio Source</label>
  <select id="audioSource"></select>
</div>
<div>
  <label for="audioOutput">audio Output</label>
  <select id="audioOutput"></select>
</div>
<div>
  <label for="videoSource">video Source</label>
  <select id="videoSource"></select>
</div>
<div>
  <label for="filter">Filter:</label>
  <select id="filter">
    <option value="none">None</option>
    <option value="blur">blur</option>
    <option value="grayscale">Grayscale</option>
    <option value="invert">Invert</option>
    <option value="sepia">sepia</option>
  </select>
</div>
<div>
  <button id="snapshot">Take snapshot</button>
</div>
<div>
  <canvas id="picture"></canvas>
</div>

<table>
  <tr>
    <td>
      <video autoplay playsinline id="player"></video>
    </td>
    <td>
      <video playsinline id="recplayer"></video>
    </td>
    <td>
      <div id="constraints" class="output"></div>
    </td>
  </tr>
  <tr>
    <td>
      <button id="recordBtn">Start Record</button>
    </td>
    <td>
      <button id="recplayBtn" disabled>Play</button>
    </td>
    <td>
      <button id="downloadBtn" disabled>Download</button>
    </td>
  </tr>
</table>

<!--https://webrtc.github.io/adapter/adapter-latest.js-->
<!--https://webrtchacks.github.io/adapter/adapter-latest.js-->
<!--https://github.com/webrtchacks/adapter-->
<!--https://www.npmjs.com/package/webrtc-adapter-->
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script>
  // const audioSource = document.querySelector('select#audioSource'); //设置为id 已经自动获取
  // const audioOutput = document.querySelector('select#audioOutput');
  // const videoSource = document.querySelector('select#videoSource');
  const videoplay = document.querySelector('video#player');
  const output = document.querySelector('div#constraints');

  start();

  videoSource.onchange = start;
  filter.onchange = function(){
    videoplay.className = filter.value;
  }

  picture.width = 320;
  picture.height = 240;
  snapshot.onclick = () => {
    picture.className = filter.value; //todo 虽然我们浏览器里看是生效了, 但如果我们点击保存, 其实是没有生效的

    picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
  };

  let mediaRecorder,
    buffer;

  recordBtn.onclick = () => {
    if(recordBtn.textContent === 'Start Record'){
      startRecord();
      recordBtn.textContent = 'Stop Record';
      recplayBtn.disabled = true;
      downloadBtn.disabled = true;
    }else {
      stopRecord();
      recordBtn.textContent = 'Start Record';
      recplayBtn.disabled = false;
      downloadBtn.disabled = false;
    }
  };
  function startRecord(){
    buffer = [];

    const options = {
      mimeType: 'video/webm;codecs=vp8' //只有音频的话就是audio
    }

    if(!MediaRecorder.isTypeSupported(options.mimeType)){ //https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/isTypeSupported
      console.error(`${options.mimeType} is not supported!`);
      return;
    }
    try {
      mediaRecorder = new MediaRecorder(window.stream, options);

    }catch (e){
      console.error(`Failed to create MediaRecorder:',e`);
      return;
    }

    mediaRecorder.ondataavailable = handleDataAvailable;
    mediaRecorder.start(10);
  }
  function handleDataAvailable(e){
    if (e && e.data && e.data.size > 0) {
      buffer.push(e.data);
    }
  }
  function stopRecord(){
    mediaRecorder.stop()
  }
  recplayBtn.onclick = () => {
    const blob = new Blob(buffer, {type: 'video/webm'}); //这里指定的video/webm 对应你 new MediaRecorder 时传递的options里的参数
    recplayer.src = window.URL.createObjectURL(blob);
    // recplayer.srcObject = null; // 直播时用的
    recplayer.controls = true;
    recplayer.play();
  };
  downloadBtn.onclick = ()=>{
    const blob = new Blob(buffer, {type: 'video/webm'});
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.style.display = 'none';
    a.download = 'aaa.webm';
    a.click();
  }

  function start(){
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      console.log('getUserMedia is not supported!');
    }else {
      const deviceId = videoSource.value;

      const MediaStreamConstrains = {
        video: {
          width: 640,
          height: 480,
          frameRate: 15,
          deviceId: deviceId ? deviceId : undefined,
          facingMode: 'environment'
        },
        audio: {
          echoCancellation:false,
          noiseSuppression:true
        }
      };

      navigator.mediaDevices.getUserMedia(MediaStreamConstrains)
        .then(gotMediaStream)
        .then(gotDevices)
        .catch(handleError);
    }
  }


  function gotMediaStream(stream){
    videoplay.srcObject = stream;

    const videoTrack = stream.getVideoTracks()[0];
    const videoConstraints = videoTrack.getSettings();
    output.textContent = JSON.stringify(videoConstraints, null, 2);
    /*

{ "aspectRatio": 1.3333333333333333, "brightness": 128, "colorTemperature": 4000, "contrast": 32, "deviceId": "72b3fbb417ee8fa5893e995be299d165655e927abff4ae212069aeb7a83e7ebf", "exposureMode": "continuous", "exposureTime": 156.25, "facingMode": "user", "frameRate": 15, "groupId": "92e54ff32f586a78e5974dc9037074fee047fe0702456b1608ec27c0cd2a8281", "height": 480, "resizeMode": "crop-and-scale", "saturation": 64, "sharpness": 2, "whiteBalanceMode": "continuous", "width": 640 }
    */

    window.stream = stream;

    return navigator.mediaDevices.enumerateDevices();
  }

  function handleError(error){
    console.error('getUserMedia error:', error);
  }

  let hasSet = false;
  function gotDevices(deviceInfos) {
    if(hasSet) return;
    hasSet = true;
    deviceInfos.forEach((deviceInfo) => {
      const option = document.createElement('option');
      option.text = deviceInfo.label;
      option.value = deviceInfo.deviceId;
      switch (deviceInfo.kind) {
        case 'audioinput':
          audioSource.appendChild(option);
          break;
        case 'audiooutput':
          audioOutput.appendChild(option);
          break;
        case 'videoinput':
          videoSource.appendChild(option);
      }
    });
  }

</script>
</body>
</html>
